package net;

public class Test {
    int k = 1;
    String name;

    public Test(String name) {
        this.name = name;
    }

    public Test() {
        eat();
    }
    public void eatFunc() {
        this.eat();
    }
    public static void eatFunc(Test t) {
        t.eat();
    }
    public void eat() {
        System.out.println("TEST --> eat()");
    }
    public void run() {
        System.out.println("TEST --> run()");
    }

    public static void main(String[] args) {
        Test t = new Test2();
        //由此可见，在实例化的时候，构造方法里面方法的调用依然遵循动态绑定
    }

    public static void main1(String[] args) {
        Test t = new Test3();
//        Test2 t2 = (Test2)t;
//        t2.eat();
//        Test3 t3 = (Test3)t;
        if(t instanceof Test3) {
            Test3 t3 = (Test3) t;
            eatFunc(t3);
        } else if(t instanceof Test2) {
            Test2 t2 = (Test2) t;
            eatFunc(t2);
        }
    }
    public static void main0(String[] args) {
//        Test test = new Test2();
//        test.eat();
////        test.bark();//error
//        test.run();
        /*
        * 这三个方法说明
        * 1. 当向上转型的时候，如果要成功调用方法，那么前者（Test这个父类）必须要有对应的方法
        * 2. 而在调用方法的时候，是从后者开始寻找（Test2这个子类），如果有则调用子类，没有
        * 就去找到上一级，直到找到对应的方法为止。
        */

        Test t = new Test();
        Test t2 = new Test2();
        Test t3 = new Test3();
//        t.eatFunc();
//        t2.eatFunc();
//        t3.eatFunc();
        eatFunc(t);//没有对应的对象 有对象的情景；t.eatFunc(), 所以eatFunc 要加static
        eatFunc(t2);
        eatFunc(t3);
        t2.eat();
    }
}
class Test3 extends Test {
    @Override
    public void eat() {
        System.out.println("TEST3 --> eat()");
    }
}
class Test2 extends Test {
    @Override
    public void eat() {
        System.out.println("TEST2 --> eat()");
    }
    public void bark() {
        System.out.println("TEST2 --> bark()");
    }
    public Test2() {
        super();
    }

    int a = 1;
    int b = 2;
}
